<?php
/**
 *
 * @author Kovács Tamás
 * @version
 */
require_once 'Zend/Loader/PluginLoader.php';
require_once 'Zend/Controller/Action/Helper/Abstract.php';

/**
 * GetModel Action Helper
 *
 * @uses Zend_Controller_Action_Helper_Abstract
 */
class Smithy_Helper_GetModel extends Zend_Controller_Action_Helper_Abstract
{
    /**
     * @var Zend_Loader_PluginLoader
     */
    public $_pluginLoader;

    protected $_models = array();

    protected $_applicationPrefix = '';
    protected static $_instance = NULL;

    /**
     * Constructor: initialize plugin loader
     *
     * @return void
     */
    public function __construct ()
    {
        $this->_pluginLoader = new Zend_Loader_PluginLoader();
    }

    /**
     * Factory method.
     *
     * @return Smithy_Helper_GetModel
     */
    public static function getInstance()
    {
    	if (NULL === self::$_instance) {
    	    self::$_instance = new self;
    	}

    	return self::$_instance;
    }

    /**
     * Sets the application wide prefix for models.
     *
     * @param string The prefix without the '_' at the end.
     * @return Smithy_Helper_GetModel
     */
    public function setApplicationPrefix($prefix)
    {
        $this->_applicationPrefix = $prefix . '_';

        return $this;
    }

    /**
     * Returns with the pluginloader, with the apropiate prefixes and paths.
     *
     * @param string $module
     * @return Zend_Loader_PluginLoader
     */
    protected function _getPluginLoader($module = null)
    {
        $module     = empty($module) ? $this->getRequest()->getModuleName() : (string)$module;
        $front      = $this->getFrontController();

        if (empty($module)) {
            $module = $front->getDispatcher()->getDefaultModule();
        }

        $moduleDirectory = $front->getControllerDirectory($module);
        $modelsDirectory = dirname($moduleDirectory) . '/models';

        $prefix = (('default' == $module) ? '' : ucfirst($module) . '_');
        $this->_pluginLoader->addPrefixPath($this->_applicationPrefix . $prefix, $modelsDirectory);

        return $this->_pluginLoader;
    }

    /**
     * Load a model class and return an object instance
     *
     * @param string $model
     * @param string $module
     * @return object
     */
    public function getModel($modelName, $module = null)
    {
        $modelClass = $this->_getPluginLoader(strtolower($module))->load(
            ucfirst((string) $modelName)
        );

        if (!array_key_exists($modelClass, $this->_models)) {
            $this->_models[$modelClass] = new $modelClass;
        }

        return $this->_models[$modelClass];
    }

    /**
     * Proxy to getModel()
     *
     * @param  string $model
     * @return object
     */
    public function direct($model, $module = null)
    {
        return $this->getModel($model, $module);
    }
}

